package com.ybwh.springboot2.util;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Preconditions;
import com.ybwh.springboot2.common.TokenInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <p>
 * token 工具
 * </p>
 *
 * @author fanbeibei
 * @version V1.0
 * @since 2019/5/16 21:38
 */
@Component
@Slf4j
public class TokenUtil implements EnvironmentAware {
    public static final String TOKEN_AES_SERCRET_KEY = "token.aes.secret";

    public static final String TOKEN_KEY = "_TOKEN";

    private static String TOKEN_AES_SECRET;

    /**
     * 获取token
     *
     * @param request
     * @return
     */
    public static String getToken(HttpServletRequest request) {
        String token = request.getHeader(TOKEN_KEY);
        if(StringUtils.isNotBlank(token)){
            return token;
        }

        return CookieUtil.getValue(request, TOKEN_KEY);
    }

    /**
     * 设置token
     *
     * @param response
     */
    public static void setToken(HttpServletResponse response, String token) {
        if (null == token) {
            token = "";
        }
        CookieUtil.set(response, TOKEN_KEY, token, true);
    }

    /**
     * 生成token
     *
     * @param tokenInfo
     * @return
     */
    public static String encodeToken(TokenInfo tokenInfo) {
        Preconditions.checkNotNull(tokenInfo);

        if (StringUtils.isBlank(TOKEN_AES_SECRET)) {
            throw new IllegalStateException("can not get token AES secret!!");
        }

        return AESUtil.encrypt(JSON.toJSONString(tokenInfo), TOKEN_AES_SECRET);
    }

    /**
     * 解码token
     *
     * @param token
     * @return
     */
    public static TokenInfo decodeToken(String token) {
        if (StringUtils.isBlank(token)) {
            return null;
        }

        if (StringUtils.isBlank(TOKEN_AES_SECRET)) {
            throw new IllegalStateException("can not get token AES secret!!");
        }

        try {
            String plaintext = AESUtil.decrypt(token, TOKEN_AES_SECRET);
            return JSON.parseObject(plaintext, TokenInfo.class);
        } catch (Exception e) {

            log.error("decodeToken error,token={},{}", token, ExceptionUtils.getStackTrace(e));
        }

        return null;

    }

    /**
     * token是否过期
     *
     * @param token
     * @return
     */
    public static boolean isExpired(String token) {
        if (StringUtils.isBlank(token)) {
            return true;
        }

        TokenInfo tokenInfo = decodeToken(token);
        return isExpired(tokenInfo);
    }


    /**
     * token是否过期
     *
     * @param tokenInfo
     * @return
     */
    public static boolean isExpired(TokenInfo tokenInfo) {
        if (null == tokenInfo) {
            return true;
        }

        if (tokenInfo.getTime() + tokenInfo.getExpire() > System.currentTimeMillis()) {
            return false;
        }

        return true;
    }

    @Override
    public void setEnvironment(Environment environment) {
        TOKEN_AES_SECRET = environment.getProperty(TOKEN_AES_SERCRET_KEY);
    }
}
